package aliyun.cx.admin.controller;

import aliyun.cx.admin.entity.Comment;
import aliyun.cx.admin.service.CommentService;
import aliyun.cx.admin.util.ConfigUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.util.StringUtils;
import org.springframework.web.util.HtmlUtils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

/**
 * 评论管理控制器
 */
@RestController
@RequestMapping("/api/comments")
@CrossOrigin(origins = "*", maxAge = 3600)
public class CommentController {

    @Autowired
    private CommentService commentService;
    
    @Autowired
    private ConfigUtil configUtil;
    
    // XSS防护正则表达式
    private static final Pattern SCRIPT_PATTERN = Pattern.compile("<script[^>]*>.*?</script>", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
    private static final int MAX_CONTENT_LENGTH = 1000; // 评论内容最大长度
    
    /**
     * 输入验证和XSS防护
     */
    private String sanitizeInput(String input) {
        if (!StringUtils.hasText(input)) {
            return "";
        }
        
        // 长度验证
        if (input.length() > MAX_CONTENT_LENGTH) {
            throw new IllegalArgumentException("评论内容不能超过" + MAX_CONTENT_LENGTH + "个字符");
        }
        
        // XSS防护 - HTML转义
        String sanitized = HtmlUtils.htmlEscape(input);
        
        // 移除潜在的脚本标签
        sanitized = SCRIPT_PATTERN.matcher(sanitized).replaceAll("");
        
        return sanitized.trim();
    }
    
    /**
     * 验证评论数据
     */
    private void validateComment(Comment comment) {
        if (comment == null) {
            throw new IllegalArgumentException("评论数据不能为空");
        }
        
        if (!StringUtils.hasText(comment.getContent())) {
            throw new IllegalArgumentException("评论内容不能为空");
        }
        
        if (comment.getUserId() == null) {
            throw new IllegalArgumentException("用户ID不能为空");
        }
        
        if (comment.getArticleId() == null) {
            throw new IllegalArgumentException("文章ID不能为空");
        }
        
        // 对评论内容进行XSS防护
        comment.setContent(sanitizeInput(comment.getContent()));
    }

    /**
     * 获取评论列表（分页，包含关联信息）
     */
    @GetMapping("/relations")
    public Map<String, Object> getCommentListWithRelations(
            @RequestParam(defaultValue = "1") int page,
            @RequestParam(defaultValue = "10") int size,
            @RequestParam(required = false) Long userId,
            @RequestParam(required = false) Long articleId,
            @RequestParam(required = false) Long parentId,
            @RequestParam(required = false) Integer status,
            @RequestParam(required = false) String content) {
        
        Map<String, Object> result = new HashMap<>();
        
        try {
            System.out.println("查询参数 - page: " + page + ", size: " + size + ", userId: " + userId + ", articleId: " + articleId + ", status: " + status);
            
            IPage<Comment> commentPage = commentService.getCommentPageWithRelations(page, size, userId, articleId, parentId, status, content);
            
            System.out.println("查询结果 - 总数: " + commentPage.getTotal() + ", 当前页记录数: " + commentPage.getRecords().size());
            
            result.put("code", 200);
            result.put("message", "获取评论列表成功");
            result.put("data", commentPage);
            
        } catch (Exception e) {
            System.err.println("获取评论列表失败: " + e.getMessage());
            e.printStackTrace();
            result.put("code", 500);
            result.put("message", "获取评论列表失败：" + e.getMessage());
        }
        
        return result;
    }

    /**
     * 获取评论列表（分页）
     */
    @GetMapping
    public Map<String, Object> getCommentList(
            @RequestParam(defaultValue = "1") int page,
            @RequestParam(defaultValue = "10") int size,
            @RequestParam(required = false) Long userId,
            @RequestParam(required = false) Long articleId,
            @RequestParam(required = false) Long parentId) {
        
        // 使用关联查询方法
        return getCommentListWithRelations(page, size, userId, articleId, parentId, null, null);
    }

    /**
     * 创建评论
     */
    @PostMapping
    public Map<String, Object> createComment(@RequestBody Comment comment) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            System.out.println("创建评论请求 - 评论内容: " + (comment != null ? comment.getContent() : "null"));
            System.out.println("创建评论请求 - 用户ID: " + (comment != null ? comment.getUserId() : "null"));
            System.out.println("创建评论请求 - 文章ID: " + (comment != null ? comment.getArticleId() : "null"));
            
            // 检查评论发布功能是否启用
            if (!configUtil.isCommentPublishEnabled()) {
                result.put("code", 403);
                result.put("message", "评论发布功能已禁用");
                return result;
            }
            
            // 输入验证和XSS防护
            validateComment(comment);
            
            System.out.println("验证通过，开始创建评论...");
            
            boolean success = commentService.createComment(comment);
            
            if (success) {
                result.put("code", 200);
                result.put("message", "创建评论成功");
                result.put("data", comment);
                
                // 记录操作日志
                System.out.println("创建评论成功 - ID: " + comment.getId() + ", 用户ID: " + comment.getUserId());
            } else {
                result.put("code", 400);
                result.put("message", "创建评论失败");
                System.err.println("创建评论服务返回失败");
            }
            
        } catch (IllegalArgumentException e) {
            result.put("code", 400);
            result.put("message", e.getMessage());
            System.err.println("创建评论参数错误: " + e.getMessage());
        } catch (Exception e) {
            result.put("code", 500);
            result.put("message", "创建评论失败：" + e.getMessage());
            System.err.println("创建评论异常: " + e.getMessage());
            e.printStackTrace();
        }
        
        return result;
    }

    /**
     * 更新评论
     */
    @PutMapping("/{id}")
    public Map<String, Object> updateComment(@PathVariable Long id, @RequestBody Comment comment) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            // ID验证
            if (id == null || id <= 0) {
                result.put("code", 400);
                result.put("message", "无效的评论ID");
                return result;
            }
            
            comment.setId(id);
            
            // 输入验证和XSS防护
            validateComment(comment);
            
            boolean success = commentService.updateComment(comment);
            
            if (success) {
                result.put("code", 200);
                result.put("message", "更新评论成功");
                result.put("data", comment);
                
                // 记录操作日志
                System.out.println("更新评论成功 - ID: " + comment.getId());
            } else {
                result.put("code", 400);
                result.put("message", "更新评论失败");
            }
            
        } catch (IllegalArgumentException e) {
            result.put("code", 400);
            result.put("message", e.getMessage());
        } catch (Exception e) {
            result.put("code", 500);
            result.put("message", "更新评论失败：" + e.getMessage());
            System.err.println("更新评论异常: " + e.getMessage());
            e.printStackTrace();
        }
        
        return result;
    }

    /**
     * 删除评论
     */
    @DeleteMapping("/{id}")
    public Map<String, Object> deleteComment(@PathVariable Long id) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            boolean success = commentService.deleteComment(id);
            
            if (success) {
                result.put("code", 200);
                result.put("message", "删除评论成功");
            } else {
                result.put("code", 400);
                result.put("message", "删除评论失败");
            }
            
        } catch (Exception e) {
            result.put("code", 500);
            result.put("message", "删除评论失败：" + e.getMessage());
        }
        
        return result;
    }

    /**
     * 批量删除评论
     */
    @DeleteMapping("/batch")
    public Map<String, Object> batchDeleteComments(@RequestBody List<Long> ids) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            boolean success = commentService.batchDeleteComments(ids);
            
            if (success) {
                result.put("code", 200);
                result.put("message", "批量删除评论成功");
            } else {
                result.put("code", 400);
                result.put("message", "批量删除评论失败");
            }
            
        } catch (Exception e) {
            result.put("code", 500);
            result.put("message", "批量删除评论失败：" + e.getMessage());
        }
        
        return result;
    }

    /**
     * 获取评论详情（包含关联信息）
     */
    @GetMapping("/{id}")
    public Map<String, Object> getCommentDetail(@PathVariable Long id) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            Comment comment = commentService.getCommentWithRelations(id);
            
            if (comment != null) {
                result.put("code", 200);
                result.put("message", "获取评论详情成功");
                result.put("data", comment);
            } else {
                result.put("code", 404);
                result.put("message", "评论不存在");
            }
            
        } catch (Exception e) {
            result.put("code", 500);
            result.put("message", "获取评论详情失败：" + e.getMessage());
        }
        
        return result;
    }

    /**
     * 获取文章评论列表（包含关联信息）
     */
    @GetMapping("/article/{articleId}")
    public Map<String, Object> getCommentsByArticle(@PathVariable Long articleId) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            List<Comment> comments = commentService.getCommentsByArticleWithRelations(articleId);
            
            result.put("code", 200);
            result.put("message", "获取文章评论成功");
            result.put("data", comments);
            
        } catch (Exception e) {
            result.put("code", 500);
            result.put("message", "获取文章评论失败：" + e.getMessage());
        }
        
        return result;
    }

    /**
     * 获取评论统计信息
     */
    @GetMapping("/stats")
    public Map<String, Object> getCommentStats() {
        Map<String, Object> result = new HashMap<>();
        
        try {
            Object stats = commentService.getCommentStats();
            
            result.put("code", 200);
            result.put("message", "获取评论统计成功");
            result.put("data", stats);
            
        } catch (Exception e) {
            result.put("code", 500);
            result.put("message", "获取评论统计失败：" + e.getMessage());
        }
        
        return result;
    }
    
    /**
     * 获取用户评论列表（包含关联信息）
     */
    @GetMapping("/user/{userId}")
    public Map<String, Object> getCommentsByUser(@PathVariable Long userId) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            List<Comment> comments = commentService.getCommentsByUserWithRelations(userId);
            
            result.put("code", 200);
            result.put("message", "获取用户评论成功");
            result.put("data", comments);
            
        } catch (Exception e) {
            result.put("code", 500);
            result.put("message", "获取用户评论失败：" + e.getMessage());
        }
        
        return result;
    }
    
    /**
     * 审核评论
     */
    @PutMapping("/{id}/audit")
    public Map<String, Object> auditComment(@PathVariable Long id, @RequestParam Integer status) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            if (status == null || (status != 0 && status != 1 && status != 2)) {
                result.put("code", 400);
                result.put("message", "审核状态参数错误（0-待审核 1-已通过 2-已拒绝）");
                return result;
            }
            
            boolean success = commentService.auditComment(id, status);
            
            if (success) {
                result.put("code", 200);
                result.put("message", "评论审核成功");
            } else {
                result.put("code", 400);
                result.put("message", "评论审核失败");
            }
            
        } catch (Exception e) {
            result.put("code", 500);
            result.put("message", "评论审核失败：" + e.getMessage());
        }
        
        return result;
    }
    
    /**
     * 点赞评论
     */
    @PutMapping("/{id}/like")
    public Map<String, Object> likeComment(@PathVariable Long id) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            boolean success = commentService.likeComment(id);
            
            if (success) {
                result.put("code", 200);
                result.put("message", "点赞成功");
            } else {
                result.put("code", 400);
                result.put("message", "点赞失败");
            }
            
        } catch (Exception e) {
            result.put("code", 500);
            result.put("message", "点赞失败：" + e.getMessage());
        }
        
        return result;
    }
    
    /**
     * 测试接口
     */
    @GetMapping("/test")
    public Map<String, Object> test() {
        Map<String, Object> result = new HashMap<>();
        result.put("code", 200);
        result.put("message", "评论服务正常运行（支持关联查询）");
        result.put("timestamp", System.currentTimeMillis());
        result.put("features", new String[]{"关联查询", "评论审核", "点赞功能", "标签关联"});
        return result;
    }
    
    /**
     * 置顶/取消置顶评论
     */
    @PutMapping("/{id}/top")
    public Map<String, Object> toggleCommentTop(@PathVariable Long id, @RequestParam Boolean isTop) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            if (id == null || id <= 0) {
                result.put("code", 400);
                result.put("message", "无效的评论ID");
                return result;
            }
            
            if (isTop == null) {
                result.put("code", 400);
                result.put("message", "置顶状态不能为空");
                return result;
            }
            
            boolean success = commentService.toggleCommentTop(id, isTop);
            
            if (success) {
                String action = isTop ? "置顶" : "取消置顶";
                result.put("code", 200);
                result.put("message", "评论" + action + "成功");
                
                System.out.println("评论" + action + "成功 - ID: " + id);
            } else {
                result.put("code", 400);
                result.put("message", "评论置顶操作失败");
            }
            
        } catch (Exception e) {
            result.put("code", 500);
            result.put("message", "评论置顶操作失败：" + e.getMessage());
            System.err.println("评论置顶操作异常: " + e.getMessage());
            e.printStackTrace();
        }
        
        return result;
    }
    
    /**
     * 批量审核评论
     */
    @PutMapping("/batch/audit")
    public Map<String, Object> batchAuditComments(
            @RequestBody Map<String, Object> request) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            // 从请求体中获取参数
            @SuppressWarnings("unchecked")
            List<Long> ids = (List<Long>) request.get("ids");
            Integer status = (Integer) request.get("status");
            
            // 另一种可能的参数格式
            if (ids == null && request.containsKey("data")) {
                @SuppressWarnings("unchecked")
                Object data = request.get("data");
                if (data instanceof List) {
                    ids = (List<Long>) data;
                }
            }
            
            if (ids == null || ids.isEmpty()) {
                result.put("code", 400);
                result.put("message", "评论ID列表不能为空");
                return result;
            }
            
            if (status == null || (status != 0 && status != 1 && status != 2)) {
                result.put("code", 400);
                result.put("message", "审核状态参数错误（0-待审核 1-已通过 2-已拒绝）");
                return result;
            }
            
            System.out.println("批量审核请求 - IDs: " + ids + ", Status: " + status);
            
            boolean success = commentService.batchAuditComments(ids, status);
            
            if (success) {
                String statusText = getStatusText(status);
                result.put("code", 200);
                result.put("message", "批量审核成功，状态: " + statusText + "，数量: " + ids.size());
                
                System.out.println("批量审核成功 - 状态: " + statusText + ", 数量: " + ids.size());
            } else {
                result.put("code", 400);
                result.put("message", "批量审核失败");
            }
            
        } catch (Exception e) {
            result.put("code", 500);
            result.put("message", "批量审核失败：" + e.getMessage());
            System.err.println("批量审核异常: " + e.getMessage());
            e.printStackTrace();
        }
        
        return result;
    }
    
    /**
     * 获取置顶评论
     */
    @GetMapping("/top")
    public Map<String, Object> getTopComments(
            @RequestParam(required = false) Long articleId,
            @RequestParam(defaultValue = "10") Integer limit) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            List<Comment> comments = commentService.getTopComments(articleId, limit);
            
            result.put("code", 200);
            result.put("message", "获取置顶评论成功");
            result.put("data", comments);
            
        } catch (Exception e) {
            result.put("code", 500);
            result.put("message", "获取置顶评论失败：" + e.getMessage());
            System.err.println("获取置顶评论异常: " + e.getMessage());
            e.printStackTrace();
        }
        
        return result;
    }
    
    /**
     * 获取状态文本的辅助方法
     */
    private String getStatusText(Integer status) {
        switch (status) {
            case 0: return "待审核";
            case 1: return "已通过";
            case 2: return "已拒绝";
            default: return "未知";
        }
    }
    @GetMapping("/test-db")
    public Map<String, Object> testDatabase() {
        Map<String, Object> result = new HashMap<>(); 
        try {
            System.out.println("开始测试数据库连接...");
            
            // 直接查询评论表的数据数量
            long totalCount = commentService.count();
            System.out.println("评论总数: " + totalCount);
            
            result.put("code", 200);
            result.put("message", "数据库连接正常");
            result.put("totalComments", totalCount);
            
            if (totalCount > 0) {
                // 获取前5条数据
                List<Comment> comments = commentService.list();
                System.out.println("查询到的评论数量: " + comments.size());
                if (!comments.isEmpty()) {
                    System.out.println("第一条评论: " + comments.get(0).getContent());
                    result.put("firstComment", comments.get(0));
                }
                result.put("sampleComments", comments.stream().limit(5).toList());
            }
            
        } catch (Exception e) {
            System.err.println("数据库测试失败: " + e.getMessage());
            e.printStackTrace();
            result.put("code", 500);
            result.put("message", "数据库连接失败：" + e.getMessage());
        }
        return result;
    }
    
    /**
     * 举报评论
     */
    @PostMapping("/{id}/report")
    public Map<String, Object> reportComment(@PathVariable Long id, @RequestBody Map<String, String> request) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            String reason = request.get("reason");
            if (!StringUtils.hasText(reason)) {
                result.put("code", 400);
                result.put("message", "举报原因不能为空");
                return result;
            }
            
            // 对举报原因进行XSS防护
            reason = sanitizeInput(reason);
            
            boolean success = commentService.reportComment(id, reason);
            
            if (success) {
                result.put("code", 200);
                result.put("message", "举报提交成功");
                
                System.out.println("举报评论成功 - 评论ID: " + id + ", 原因: " + reason);
            } else {
                result.put("code", 400);
                result.put("message", "举报提交失败");
            }
            
        } catch (Exception e) {
            result.put("code", 500);
            result.put("message", "举报提交失败：" + e.getMessage());
            System.err.println("举报评论异常: " + e.getMessage());
            e.printStackTrace();
        }
        
        return result;
    }
    
    /**
     * 获取评论举报列表
     */
    @GetMapping("/{commentId}/reports")
    public Map<String, Object> getCommentReports(@PathVariable Long commentId) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            List<Map<String, Object>> reports = commentService.getCommentReports(commentId);
            
            result.put("code", 200);
            result.put("message", "获取举报记录成功");
            result.put("data", reports);
            
        } catch (Exception e) {
            result.put("code", 500);
            result.put("message", "获取举报记录失败：" + e.getMessage());
        }
        
        return result;
    }
    
    /**
     * 测试原始SQL查询
     */
    @GetMapping("/test-sql")
    public Map<String, Object> testSqlQuery() {
        Map<String, Object> result = new HashMap<>();
        try {
            // 使用MyBatis-Plus直接查询，不使用关联查询
            List<Comment> directComments = commentService.list();
            result.put("code", 200);
            result.put("message", "直接查询成功");
            result.put("directQueryCount", directComments.size());
            
            if (!directComments.isEmpty()) {
                result.put("firstComment", directComments.get(0));
            }
            
            // 测试关联查询
            try {
                List<Comment> relatedComments = commentService.getCommentsByArticleWithRelations(1L);
                result.put("relatedQueryCount", relatedComments.size());
                if (!relatedComments.isEmpty()) {
                    result.put("firstRelatedComment", relatedComments.get(0));
                }
            } catch (Exception e) {
                result.put("relatedQueryError", e.getMessage());
            }
            
        } catch (Exception e) {
            result.put("code", 500);
            result.put("message", "SQL查询失败：" + e.getMessage());
            e.printStackTrace();
        }
        return result;
    }
}
